package com.bingxue.edu.management.education.controller;

import com.bingxue.edu.framework.common.model.PageQuery;
import com.bingxue.edu.framework.common.model.Pagination;
import com.bingxue.edu.framework.common.model.Response;
import com.bingxue.edu.framework.excel.model.ClassStudentExportModel;
import com.bingxue.edu.framework.excel.util.ExcelUtil;
import com.bingxue.edu.framework.mybatis.query.QueryBuilder;
import com.bingxue.edu.framework.security.ApiResource;
import com.bingxue.edu.management.education.model.query.ClassPrevListQuery;
import com.bingxue.edu.management.education.model.query.ClassQuery;
import com.bingxue.edu.management.education.model.query.ClassWithPermissionQuery;
import com.bingxue.edu.management.education.model.req.ClassInfoCreateReq;
import com.bingxue.edu.management.education.model.req.ClassInfoUpdateReq;
import com.bingxue.edu.management.education.model.req.ClassSaleUpdateReq;
import com.bingxue.edu.management.education.model.req.SelectiveImportPreStudentReq;
import com.bingxue.edu.management.education.model.resp.ClassDetailResp;
import com.bingxue.edu.management.education.model.resp.ClassInfoExportResp;
import com.bingxue.edu.management.education.model.resp.ClassInfoResp;
import com.bingxue.edu.management.education.model.resp.ClassInfoSummaryResp;
import com.bingxue.edu.management.education.model.resp.ClassNameInfoResp;
import com.bingxue.edu.management.education.model.resp.ClassStudentResp;
import com.bingxue.edu.management.education.model.resp.ImportPrevStudentResp;
import com.bingxue.edu.management.education.model.resp.UnpaidStudentResp;
import com.bingxue.edu.management.education.service.ClassInfoService;
import com.bingxue.edu.management.education.service.ClassStudentService;
import com.mybatisflex.core.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;

/**
 * 班级管理
 *
 * @author zq
 * @since 2024/08/24
 */
@Tag(name = "班级管理")
@RestController
@RequestMapping("/education/class")
@RequiredArgsConstructor
public class ClassInfoController {

    private final ClassInfoService classInfoService;
    private final ClassStudentService classStudentService;

    @Operation(summary = "班级总览信息")
    @ApiResource("edu:class:read")
    @GetMapping("/summary")
    public Response<ClassInfoSummaryResp> summary(ClassQuery query) {
        return Response.success(classInfoService.getClassInfoSummary(query));
    }

    @Operation(summary = "分页查询班级")
    @ApiResource("edu:class:read")
    @GetMapping("/page")
    public Response<Pagination<ClassInfoResp>> page(ClassQuery query, @Validated PageQuery pageQuery) {
        return Response.success(Pagination.of(classInfoService.getClassInfoPage(query, pageQuery)));
    }

    @Operation(summary = "导出班级信息")
    @ApiResource("edu:class:read")
    @GetMapping("/export")
    public void export(ClassQuery query, HttpServletResponse response) {
        List<ClassInfoExportResp> records = classInfoService.getClassInfoList(query).stream().map(ClassInfoExportResp::of).toList();
        ExcelUtil.export(records, "班级列表", ClassInfoExportResp.class, response);
    }

    @Operation(summary = "查询班级列表")
    @ApiResource("edu:class:read")
    @GetMapping("/list-prev")
    public Response<List<ClassNameInfoResp>> listPrevClassInfo(@Validated ClassPrevListQuery query) {
        QueryWrapper queryWrapper = QueryBuilder.build(query);
        List<ClassNameInfoResp> list = classInfoService.getMapper().selectListWithRelationsByQueryAs(queryWrapper, ClassNameInfoResp.class);
        return Response.success(list);
    }

    @Operation(summary = "分页查询有权限的班级列表")
    @ApiResource("edu:class:read")
    @GetMapping("/pageWithPermission")
    public Response<Pagination<ClassInfoResp>> pageWithPermission(@Validated ClassWithPermissionQuery query, @Validated PageQuery pageQuery) {
        return Response.success(Pagination.of(classInfoService.getClassInfoPageWithPermission(query, pageQuery)));
    }

    @Operation(summary = "查询班级详情")
    @ApiResource("edu:class:read")
    @GetMapping("/detail/{id}")
    public Response<ClassDetailResp> getDetailById(@PathVariable String id) {
        return Response.success(classInfoService.getDetailById(id));
    }

    @Operation(summary = "创建班级")
    @ApiResource("edu:class:write")
    @PostMapping("/create")
    public Response<String> create(@RequestBody @Validated ClassInfoCreateReq req) {
        return Response.success(classInfoService.create(req));
    }

    @Operation(summary = "导入前序班级学生")
    @ApiResource("edu:class:write")
    @PostMapping("/import-prev-student")
    public Response<ImportPrevStudentResp> importPrevClassStudent(@RequestParam @NotNull String classId) {
        return Response.success(classInfoService.importPrevClassStudent(classId));
    }

    @Operation(summary = "更新上架状态")
    @ApiResource("edu:class:write")
    @PostMapping("/update-sale-status")
    public Response<Void> updateSaleStatus(@RequestBody @Validated ClassSaleUpdateReq classSaleUpdateReq) {
        classInfoService.updateSaleStatus(classSaleUpdateReq);
        return Response.success();
    }

    @Operation(summary = "更新班级数据")
    @ApiResource("edu:class:write")
    @PostMapping("/update/{id}")
    public Response<Void> update(@RequestBody @Validated ClassInfoUpdateReq req, @PathVariable String id) {
        classInfoService.updateByClassId(req,id);
        return Response.success();
    }

    @Operation(summary = "删除班级")
    @ApiResource("edu:class:write")
    @PostMapping("/delete/{id}")
    public Response<Void> deleteById(@PathVariable String id) {
        classInfoService.deleteClassById(id);
        return Response.success();
    }

    @Operation(summary = "关闭班级")
    @ApiResource("edu:class:write")
    @PostMapping("/close/{id}")
    public Response<Void> closeById(@PathVariable String id) {
        classInfoService.closeClassById(id);
        return Response.success();
    }

    @Operation(summary = "查询班级学员")
    @ApiResource("edu:class:read")
    @GetMapping("/student/list/{id}")
    public Response<List<ClassStudentResp>> getClassStudentList(@PathVariable String id) {
        return Response.success(classStudentService.getStudentListByClassId(id));
    }

    @Operation(summary = "导出班级学员")
    @ApiResource("edu:class:export")
    @GetMapping(value = "/student/export/{id}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void exportClassStudent(@PathVariable String id, HttpServletResponse response) throws IOException {
        List<ClassStudentExportModel> records = classStudentService.getStudentExportModelListByClassId(id);
        ExcelUtil.export(records, "班级学生名单", ClassStudentExportModel.class, response);
    }

    @Operation(summary = "选择性导入前序班级学生信息")
    @ApiResource("edu:class:write")
    @PostMapping("/select-import-prev-student/{classId}")
    public Response<ImportPrevStudentResp> selectiveImportPrevClassStudent(@RequestBody SelectiveImportPreStudentReq req,@PathVariable String classId) {
        return Response.success(classInfoService.selectiveImportPrevClassStudent(req,classId));
    }

    @Operation(summary = "未支付学员信息列表")
    @ApiResource("edu:class:read")
    @GetMapping("/unpaid-student/{classId}")
    public Response<List<UnpaidStudentResp>> getUnPaidStudentList(@PathVariable String classId) {
        return Response.success(classInfoService.getUnPaidStudentList(classId));
    }

}
